﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.IO;

using TLL.Config;
using TLL.Finance.Currencys;
using TLL.Finance;
using TLL.Log;
using TLL.UTL;
using TLL.Finance.BankOrg;

using TasksLog.Conf;
using TasksLog.Statistics;
using TasksLog.Properties;

namespace TasksLog
{
    public enum InitializeType : int
    {
        Data,
        DetailData,
        ConfData,
        Progress,
        Notify,
        Currency,
        CashDetail,
        OrganizationCurrency,
        Projects,
        ToolTip
    }
    public partial class Main : Form
    {
        private Loader Loader = null;
        public Main()
        {
            this.InitializeComponent();
            this.Location = new Point((Screen.PrimaryScreen.Bounds.Width - this.Width) / 2, this.Location.Y + 50);
            this.Initialize(new List<InitializeType>() {
                InitializeType.Currency,
                InitializeType.ConfData,
                InitializeType.Data,
                InitializeType.DetailData,
                InitializeType.Progress,
                InitializeType.Notify,
                InitializeType.CashDetail,
                InitializeType.Projects,
                InitializeType.ToolTip
            }, LoaderType.Default);
            var testForm = new test();
            testForm.Show();
        }

        #region Initialize

            private void InitializeData(string findInput = "", DateTime? findDate = null)
            {
                this.ClearData();
                var index = 0;
                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                    {
                        MainConf.Items = repository.Get();
                        var items = findInput == string.Empty ? MainConf.Items.Take(20) : MainConf.Items.Where(x => x.Text.Contains(findInput)).Take(20).ToList();
                        items = findDate.HasValue ? items.Where(x => x.Create.ToShortDateString() == findDate.Value.ToShortDateString() || (x.Complite.HasValue && x.Complite.Value.ToShortDateString() == findDate.Value.ToShortDateString())).Take(20).ToList() : items;
                        foreach (var item in items)
                        {
                            var textobj = new TableItem { text = item.Text, ID = item.ID };
                            this.LBText.Items.Add(textobj);

                            var time = item.GetTime();

                            this.LBTime.Items.Add(LogTime.Formated(time));
                            this.LBStatus.Items.Add(item.Status.ToString());
                            this.LBDate.Items.Add(item.Create.ToString());
                            this.LBDeadLine.Items.Add(item.DeadLine.Value.ToString());

                            var btInfo = this.BtCreate(Color.White, Color.White, Resources.Info, 
                                            ImageLayout.Center, FlatStyle.Flat, Cursors.Hand, 
                                            17, 20, 16 * index + 1, 0, 
                                            new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold, GraphicsUnit.Pixel), 
                                            new { item.ID, Index = index });

                            var btDelete = this.BtCreate(Color.FromArgb(237, 28, 36), Color.Black, Resources.Remove,
                                            ImageLayout.Center, FlatStyle.Flat, Cursors.Hand,
                                            17, 22, 16 * index + 1, 49,
                                            new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold, GraphicsUnit.Pixel),
                                            new { item.ID, Index = index });

                            var btEdit = this.BtCreate(Color.FromArgb(255, 242, 0), Color.Black, Resources.Edit,
                                            ImageLayout.Center, FlatStyle.Flat, Cursors.Hand,
                                            17, 25, 16 * index + 1, 25,
                                            new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold, GraphicsUnit.Pixel),
                                            new { item.ID, Index = index });

                            var btComplite = this.BtCreate(Color.Green, Color.Black, Resources.Complite,
                                            ImageLayout.Center, FlatStyle.Flat, Cursors.Hand,
                                            17, 18, 16 * index + 1, 19,
                                            new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold, GraphicsUnit.Pixel),
                                            new { item.ID, Index = index });

                            var btError = this.BtCreate(Color.Red, Color.Black, Resources.Error,
                                            ImageLayout.Center, FlatStyle.Flat, Cursors.Hand,
                                            17, 23, 16 * index + 1, 3,
                                            new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold, GraphicsUnit.Pixel),
                                            new { item.ID, Index = index });

                            var btStart = this.BtCreate(Color.Red, Color.Black, Resources.Play,
                                            ImageLayout.Center, FlatStyle.Flat, Cursors.Hand,
                                            17, 18, 16 * index + 1, 3,
                                            new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold, GraphicsUnit.Pixel),
                                            new { item.ID, Index = index, Enable = false });

                            btDelete.Click += this.BtTableDelete_Click;
                            btEdit.Click += this.BtTableEdit_Click;
                            btError.Click += this.BtTableError_Click;
                            btComplite.Click += this.BtTableComplite_Click;
                            btStart.Click += this.BtTableStart_Click;
                            btInfo.Click += this.BtTableInfo_Click;

                            if (item.Status == LogStatuses.Wait || item.Status == LogStatuses.Error)
                            {
                                btEdit.Left = 36;
                                btEdit.Width = 18;
                                btDelete.Left = 53;
                                btDelete.Width = 18;
                                this.PnControl.Controls.Add(btComplite);
                                this.PnControl.Controls.Add(btStart);
                            }
                            else
                                this.PnControl.Controls.Add(btError);

                            this.PnControl.Controls.Add(btEdit);
                            this.PnControl.Controls.Add(btDelete);
                            this.PnInfoControl.Controls.Add(btInfo);

                            this.TTNotise.SetToolTip(btDelete, "Delete");
                            this.TTNotise.SetToolTip(btEdit, "Edit");
                            this.TTNotise.SetToolTip(btError, "Error");
                            this.TTNotise.SetToolTip(btInfo, "Info");
                            this.TTNotise.SetToolTip(btComplite, "Complite");
                            this.TTNotise.SetToolTip(btStart, "Start");

                            this.DTPAddDeadLine.Value = DateTime.Now.AddDays(3);

                            index++;
                        }
                    }
                    else
                        this.Close();
            }
            private void InitializeCurrency()
            {
                var organizations = new List<Organization>();
                using (var organizationRepository = new OrganizationCurrencysRepository(NITasks))
                    if (organizationRepository.Access)
                        organizations = organizationRepository.Get();
                    else return;

                using (var repository = new CurrencyRepository(CashRateType.CashRate, Parametrs.CashRate, Parametrs.DebugURL, null))
                    if (repository.Access)
                    {
                        var coll = repository.Currencys;
                        foreach (var currency in coll)
                        {
                            double countBuy = 0;
                            double countaSale = 0;
                            int countOrganization = 0;

                            foreach (var organization in organizations)
                            {
                                var value = organization.Currencys.FirstOrDefault(x => x.Type == currency.Type) == null ? 0 : organization.Currencys.FirstOrDefault(x => x.Type == currency.Type).Buy;
                                countBuy += value;
                                value = organization.Currencys.FirstOrDefault(x => x.Type == currency.Type) == null ? 0 : organization.Currencys.FirstOrDefault(x => x.Type == currency.Type).Sale;
                                countaSale += value;
                                countOrganization = value != 0 ? countOrganization + 1 : countOrganization;
                            }

                            var CurrencyRate = organizations
                                .Where(x => x.Currencys.FirstOrDefault(y => y.Type == currency.Type) != null)
                                .OrderBy(x => x.Currencys.FirstOrDefault(y => y.Type == currency.Type).Buy)
                                .Reverse();

                            currency.MaxRate = CurrencyRate.FirstOrDefault().Currencys.FirstOrDefault(x => x.Type == currency.Type).Buy;
                            currency.MinRate = CurrencyRate.LastOrDefault().Currencys.FirstOrDefault(x => x.Type == currency.Type).Buy;

                            currency.AverageBuyRate = countBuy / countOrganization;
                            currency.AverageSaleRate = countaSale / countOrganization;
                        }

                        MainConf.Currencys = coll;

                        this.LBRUB.Items.Clear();
                        this.LBRUB.Items.Add(MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.RUB).AverageBuyRate.ToString("0.00") + "/" + MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.RUB).AverageSaleRate.ToString("0.00"));

                        this.LBUSDUK.Items.Clear();
                        this.LBUSDUK.Items.Add(MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.USD).AverageBuyRate.ToString("0.00") + "/" + MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.USD).AverageSaleRate.ToString("0.00"));

                        this.LBMAXRUBUK.Items.Clear();
                        this.LBMAXRUBUK.Items.Add(MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.RUB).MaxRate.ToString("0.00"));

                        this.LBMINRUBUK.Items.Clear();
                        this.LBMINRUBUK.Items.Add(MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.RUB).MinRate.ToString("0.00"));

                        this.LBMAXUSDUK.Items.Clear();
                        this.LBMAXUSDUK.Items.Add(MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.USD).MaxRate.ToString("0.00"));

                        this.LBMINUSDUK.Items.Clear();
                        this.LBMINUSDUK.Items.Add(MainConf.Currencys.FirstOrDefault(x => x.Type == CurrencyType.USD).MinRate.ToString("0.00"));
                    }
                    else
                    {
                        MainConf.Currencys.Clear();
                        return;
                    }

                using (var repository = new RUSCurrencyRepository(NITasks))
                    if (repository.Access)
                    {
                        MainConf.Currencys.AddRange(repository.Get());
                    }
                    else
                    {
                        MainConf.Currencys.Clear();
                        return;
                    }

                this.LBUSDRUS.Items.Clear();
                this.LBUSDRUS.Items.Add(Currency.Formated(MainConf.Currencys.FirstOrDefault(x => x.Country == CurrencyCountry.Russian && x.Type == CurrencyType.USD)));
            }
            private void InitializeDetailData()
            {
                this.ClearDetailDate();
                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                    {
                        var allLog = new List<LogDate>();
                        var allTime = new LogTime();

                        foreach (var item in repository.Get())
                            if (item.Log != null)
                            {
                                allLog.AddRange(item.Log);
                                allTime.Add(item.GetTime());
                            }

                        MainConf.Session.WorkTime = allTime;

                        foreach (var item in allLog.GroupBy(x => x.Date).OrderBy(x => x.Key).Reverse().Take(8))
                        {
                            LBDetailDate.Items.Add(item.Key.Value.ToShortDateString());

                            var time = LogTime.Empty;
                            foreach (var timeitem in item)
                                time.Add(timeitem.Time);

                            if (DateTime.Now.ToShortDateString() == item.Key.Value.ToShortDateString())
                                MainConf.Session.ToDayWorkTime = new LogTime(time.Hour, time.Minutes, time.Second);

                            var money = Money.Calculate(
                                time,
                                MainConf.Setting.CashPerH,
                                MainConf.Currencys,
                                MainConf.Setting.CurrencyType);

                            this.LBDetailRUB.Items.Add(money.Where(x => x.Key == CurrencyType.RUB).FirstOrDefault().Value.ToString("0.00"));
                            this.LBDetailUAH.Items.Add(money.Where(x => x.Key == CurrencyType.UAH).FirstOrDefault().Value.ToString("0.00"));
                            this.LBDetailUSD.Items.Add(money.Where(x => x.Key == CurrencyType.USD).FirstOrDefault().Value.ToString("0.00"));//ToString("C"));

                            this.LBDetailTime.Items.Add(LogTime.Formated(time));
                        }

                        var allmoney =
                            Money.Calculate(
                                MainConf.Session.WorkTime,
                                MainConf.Setting.CashPerH,
                                MainConf.Currencys,
                                MainConf.Setting.CurrencyType);

                        this.LBDetailRUB.Items.Add(allmoney.FirstOrDefault(x => x.Key == CurrencyType.RUB).Value.ToString("0.00"));
                        this.LBDetailUAH.Items.Add(allmoney.FirstOrDefault(x => x.Key == CurrencyType.UAH).Value.ToString("0.00"));
                        this.LBDetailUSD.Items.Add(allmoney.FirstOrDefault(x => x.Key == CurrencyType.USD).Value.ToString("0.00"));//ToString("C"));
                        this.LBDetailTime.Items.Add(LogTime.Formated(allTime));
                    }
            }
            private void InitializeCashDetailData()
            {
                this.LbToDayCash.Text = Money.Formated(Money.Calculate(
                        MainConf.Session.ToDayWorkTime,
                        MainConf.Setting.CashPerH,
                        MainConf.Currencys,
                        MainConf.Setting.CurrencyType));
            }
            private void InitializeConfData()
            {
                using (var repository = new ConfRepository(Parametrs.ConfURL, Parametrs.DebugURL))
                    if (repository.Access)
                    {
                        var config = repository.Get().FirstOrDefault();

                        MainConf.Setting.CashPerH = config.Count;
                        MainConf.Setting.CurrencyType = config.CurrencyType;
                        MainConf.Setting.WorkStartDate = config.Date;
                        MainConf.Setting.WorkOutDate = config.OUTDate;
                        MainConf.Setting.WorkTimeCount = config.WorkTime;
                        MainConf.Currencys = MainConf.Currencys.Count() != 0 ? MainConf.Currencys : config.Currencys;
                    }
                    else
                        this.Close();
            }
            private void InitializeProgress()
            {
                try
                {
                    var daycount = Utilities.GetDayCount(MainConf.Setting.WorkStartDate.Value, MainConf.Setting.WorkOutDate.Value);

                    this.PBToDay.Maximum = MainConf.Setting.WorkTimeCount.Hour * 60 + MainConf.Setting.WorkTimeCount.Minutes;
                    this.PBToDay.Value = MainConf.Session.ToDayWorkTime.Hour * 60 + MainConf.Session.ToDayWorkTime.Minutes > PBToDay.Maximum ? PBToDay.Maximum : MainConf.Session.ToDayWorkTime.Hour * 60 + MainConf.Session.ToDayWorkTime.Minutes;

                    if (daycount != 0)
                    {
                        this.PbTotal.Maximum = daycount * MainConf.Setting.WorkTimeCount.Hour * 60 + daycount * MainConf.Setting.WorkTimeCount.Minutes;
                        this.PbTotal.Value = MainConf.Session.WorkTime.Hour * 60 + MainConf.Session.WorkTime.Minutes;
                    }
                }
                catch { MessageBox.Show("Initialize progress error!!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
            }
            private void InitializeNotify()
            {
                if (this.LBText.Items.Count != 0)
                {
                    var text = (TableItem)this.LBText.Items[MainConf.Session.SelectIndex.HasValue ? MainConf.Session.SelectIndex.Value : 0];
                    var time = this.LBTime.Items[MainConf.Session.SelectIndex.HasValue ? MainConf.Session.SelectIndex.Value : 0];

                    this.NITasks.Text = string.Format("{0} | {1}", 
                        text.text.Length > 50 ? text.text.Substring(0, 50) : text.text, 
                        time);

                    List<ToolStripMenuItem> tsmis = new List<ToolStripMenuItem>();

                    foreach (ToolStripMenuItem item in CMSTasks.Items)
                        tsmis.Add(item);

                    tsmis.FirstOrDefault().Enabled = MainConf.Session.SelectIndex.HasValue ? true : false;
                    tsmis.FirstOrDefault().Text = TmrGO.Enabled ? "Pause" : "Go";
                }
            }
            private void InitializeToolTip()
            {
                this.TTNotise.SetToolTip(TBAddNumber, "Number task");
                this.TBAddNumber.ForeColor = Color.Silver;
                this.TBAddNumber.Text = "Number";
                this.TTNotise.SetToolTip(TBAddDesc, "Desc of task");
                this.TBAddDesc.ForeColor = Color.Silver;
                this.TBAddDesc.Text = "Desc of task";
            }
            private void InitializeProjects()
            {
                using (var repository = new LogProjectRepository(Parametrs.LogProjectsURL, Parametrs.DebugURL, this.NITasks))
                    foreach (var project in repository.Get())
                        CBProjects.Items.Add(new { Text = project.Name, Value = project.ID });
                CBProjects.DisplayMember = "Text";
                CBProjects.ValueMember = "Value";
            }
            private void Initialize(List<InitializeType> Types, LoaderType TypeLoader, bool Load = true)
            {
                if (this.Loader != null)
                    this.Loader.Type = TypeLoader;
                else
                    this.Loader = new Loader(this, TypeLoader);

                if (Load) this.Loader.Start();

                foreach(var type in Types)
                    switch (type)
                    {
                        case InitializeType.ConfData  : this.InitializeConfData(); break;
                        case InitializeType.Data      : this.InitializeData(); break;
                        case InitializeType.DetailData: this.InitializeDetailData(); break;
                        case InitializeType.Progress  : this.InitializeProgress(); break;
                        case InitializeType.Notify    : this.InitializeNotify(); break;
                        case InitializeType.Currency  : this.InitializeCurrency(); break;
                        case InitializeType.CashDetail: this.InitializeCashDetailData(); break;
                        case InitializeType.Projects  : this.InitializeProjects(); break;
                        case InitializeType.ToolTip   : this.InitializeToolTip(); break;
                    }
                this.Loader.Stop();
                this.WindowState = FormWindowState.Normal;
            }
            private void Initialize(InitializeType Type, LoaderType TypeLoader, bool Load = true)
            {
                if (this.Loader != null)
                    this.Loader.Type = TypeLoader;
                else
                    this.Loader = new Loader(this, TypeLoader);

                if (Load) this.Loader.Start();

                switch (Type)
                {
                    case InitializeType.ConfData  : this.InitializeConfData(); break;
                    case InitializeType.Data      : this.InitializeData(); break;
                    case InitializeType.DetailData: this.InitializeDetailData(); break;
                    case InitializeType.Progress  : this.InitializeProgress(); break;
                    case InitializeType.Notify    : this.InitializeNotify(); break;
                    case InitializeType.Currency  : this.InitializeCurrency(); break;
                    case InitializeType.CashDetail: this.InitializeCashDetailData(); break;
                    case InitializeType.Projects  : this.InitializeProjects(); break;
                    case InitializeType.ToolTip   : this.InitializeToolTip(); break;
                }
                this.Loader.Stop();
                this.WindowState = FormWindowState.Normal;
            }

        #endregion

        #region ClickEvents

            private void BtAdd_Click(object sender, EventArgs e)
            {
                if (this.TBAddDesc.Text == string.Empty) return;
                LogProject project = null;
                using (var repository = new LogProjectRepository(Parametrs.LogProjectsURL, Parametrs.DebugURL, NITasks))
                    project = repository.Get((int)(CBProjects.SelectedItem as dynamic).Value).FirstOrDefault();
                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                        repository.Create(new LogItem(
                                 TBAddNumber.Text + ": " + TBAddDesc.Text,
                                 CBPriority.Checked,
                                 DateTime.Now,
                                 null,
                                 DTPAddDeadLine.Value,
                                 project,
                                 LogStatuses.Wait,
                                 null,
                                 null));

                this.TBAddDesc.Text = string.Empty;
                this.TBAddDesc.ForeColor = Color.Silver;
                this.TBAddDesc.Text = "Desc of task";
                this.TBAddNumber.Text = string.Empty;
                this.TBAddNumber.ForeColor = Color.Silver;
                this.TBAddNumber.Text = "Number";
                this.DTPAddDeadLine.Value = DateTime.Now.AddDays(3);
                this.CBPriority.Checked = false;
                CBProjects.SelectedIndex = -1;

                this.Initialize(InitializeType.Data, LoaderType.Load);
            }
            private void BtDetail_Click(object sender, EventArgs e)
            {
                var detailCurrency = new OrganizationsForm();
                detailCurrency.Show();
            }
            private void BtSearchCancle_Click(object sender, EventArgs e)
            {
                this.TBSearch.Text = string.Empty;
                this.InitializeData();
            }
            private void LbDetail_Click(object sender, EventArgs e)
            {
                if (this.Height > 720)
                {
                    (sender as Label).Image = Resources.UpSelect;
                    for (int i = 0; i < 220; i++)
                    {
                        for (int j = 0; j < 100; j++);
                        this.Height = this.Height - 1;
                        if (this.Height < 557) break;
                    }
                }
                else
                {
                    (sender as Label).Image = Resources.DownSelect;
                    this.Initialize(InitializeType.DetailData, LoaderType.Load);
                    for (int i = 0; i < 220; i++)
                    {
                        for (int j = 0; j < 100; j++) ;
                        this.Height = this.Height + 1;
                    }
                }
            }
            private void BtUpdateCurrency_Click(object sender, EventArgs e)
            {
                this.Initialize(
                    new List<InitializeType>() { 
                    InitializeType.Currency, 
                    InitializeType.ConfData 
                }, LoaderType.Load, false);
            }
            private void BtSearch_Click(object sender, EventArgs e)
            {
                if (CBSearchDate.Checked)
                    this.InitializeData(string.Empty, DTPSearch.Value);
                else
                    this.InitializeData(TBSearch.Text);
            }

            private void TSMISetting_Click(object sender, EventArgs e)
            {
                var setting = new Setting();
                setting.ShowDialog(this);

                this.Loader = new Loader(this, LoaderType.Diagram);
                this.Loader.Start();

                Initialize(new List<InitializeType>() {
                    InitializeType.Currency,
                    InitializeType.ConfData,
                    InitializeType.DetailData,
                    InitializeType.Progress
                }, LoaderType.Load, false);

                this.Loader.Stop();
                this.Loader = new Loader(this, LoaderType.Default);
            }
            private void TSMIExit_Click(object sender, EventArgs e)
            {
                this.Close();
            }

            private void MSTSMIStatistic_Click(object sender, EventArgs e)
            {
                var statistic = new Statistic();
                statistic.ShowDialog();
            }
            private void MSTSMINew_Click(object sender, EventArgs e)
            {
                if (this.LBText.Items.Count != 0)
                {
                    if (MessageBox.Show("If don't save current log, log will be deleted. Save current log, to other logs", "Warning!!!", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Yes)
                        this.SaveToLogsAndClear();
                    else
                    {
                        this.ClearCurrentLog();
                        this.Initialize(new List<InitializeType>() {
                            InitializeType.Data,
                            InitializeType.DetailData,
                            InitializeType.Notify,
                            InitializeType.Progress,
                            InitializeType.CashDetail
                        }, LoaderType.Load);
                    }
                }
                else
                    MessageBox.Show("This log is already Empty", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            private void MSTSMIPaidAll_Click(object sender, EventArgs e)
            {
                this.SaveToLogsAndClear();
                this.Initialize(new List<InitializeType>() { 
                    InitializeType.Data,
                    InitializeType.DetailData,
                    InitializeType.Progress,
                    InitializeType.CashDetail
                }, LoaderType.Default);
            }
            private void MSTSMIPaidSelect_Click(object sender, EventArgs e)
            {
                var paidForm = new PaidTasksFrom();
                paidForm.ShowDialog(this);
                if (paidForm.isSaved)
                    this.Initialize(new List<InitializeType>() {
                        InitializeType.Data,
                        InitializeType.DetailData,
                        InitializeType.Notify,
                        InitializeType.Progress,
                        InitializeType.CashDetail
                    }, LoaderType.Load);
            }
            private void MSTSMIPBBalance_Click(object sender, EventArgs e)
            {
                var pbBalance = new PBBalance();
                if (pbBalance.Access)
                    pbBalance.Show();
            }
            private void MSTSMIPBRegCard_Click(object sender, EventArgs e)
            {
                var regForm = new RegMerchant();
                regForm.Show();
            }

            private void BtTableDelete_Click(object sender, EventArgs e)
            {
                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                    {
                        dynamic tag = (sender as Button).Tag;
                        repository.Delete((int)tag.ID);
                    }

                this.Initialize(new List<InitializeType>() { 
                    InitializeType.Data,
                    InitializeType.DetailData,
                    InitializeType.Progress,
                    InitializeType.CashDetail
                }, LoaderType.Load);
            }
            private void BtTableInfo_Click(object sender, EventArgs e)
            {
                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                    {
                        dynamic tag = (sender as Button).Tag;

                        var log = repository.Get((int)tag.ID).FirstOrDefault();
                        this.SelectIndex((int)tag.Index);

                        var taskDetailForm = new TaskDetail(log);
                        taskDetailForm.StartPosition = FormStartPosition.CenterParent;
                        taskDetailForm.ShowDialog();
                    }
            }
            private void BtTableEdit_Click(object sender, EventArgs e)
            {
                dynamic tag = (sender as Button).Tag;

                Form editform = new EditForm(MainConf.Items.FirstOrDefault(x => x.ID == (int)tag.ID));
                this.SelectIndex((int)tag.Index);
                editform.ShowDialog();

                this.Initialize(new List<InitializeType>() { 
                    InitializeType.Data,
                    InitializeType.DetailData,
                    InitializeType.Progress,
                    InitializeType.CashDetail
                }, LoaderType.Load);
            }
            private void BtTableComplite_Click(object sender, EventArgs e)
            {
                this.TmrGO.Enabled = false;
                if (MainConf.Session.InProcess)
                    MainConf.Session.Stop();

                dynamic tag = (sender as Button).Tag;

                this.LBStatus.Items[(int)tag.Index] = LogStatuses.Complite.ToString();
                this.SelectIndex((int)tag.Index);

                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                    {
                        var newItem = MainConf.Items.FirstOrDefault(x => x.ID == (int)tag.ID).Dublicate();
                        newItem.ChangeStatus(LogStatuses.Complite);
                        newItem.AddChangeLog(new LogChange(
                            DateTime.Now,
                            "Status",
                            newItem.Status.ToString()
                        ));
                        repository.Update(MainConf.Items.FirstOrDefault(x => x.ID == (int)tag.ID), newItem);
                    }

                this.Loader.Stop();

                this.Initialize(new List<InitializeType>() { 
                    InitializeType.DetailData, 
                    InitializeType.Data 
                }, LoaderType.Load, false);
            }
            private void BtTableStart_Click(object sender, EventArgs e)
            {
                var bt = (sender as Button);
                dynamic tag = (sender as Button).Tag;
                if (!(bool)tag.Enable)
                {
                    bt.BackgroundImage = Resources.Stop;
                    this.TmrGO.Enabled = true;

                    LBStatus.Items[(int)tag.Index] = "At work";
                    this.SelectIndex((int)tag.Index);

                    MainConf.Session.SelectIndex = (int)tag.Index;
                    MainConf.Session.SelectItem = MainConf.Items.FirstOrDefault(x => x.ID == (int)tag.ID);

                    MainConf.Session.Start();

                    bt.Tag = new
                    {
                        ID = (int)tag.ID,
                        Index = (int)tag.Index,
                        Enable = true
                    };
                }
                else
                {
                    bt.BackgroundImage = Resources.Play;
                    this.TmrGO.Enabled = false;

                    LBStatus.Items[(int)tag.Index] = LogStatuses.Wait.ToString();
                    this.SelectIndex((int)tag.Index);

                    MainConf.Session.Stop();
                    MainConf.Session.SaveSession();

                    bt.Tag = new
                    {
                        ID = (int)tag.ID,
                        Index = (int)tag.Index,
                        Enable = false
                    };
                }
            }
            private void BtTableError_Click(object sender, EventArgs e)
            {
                dynamic tag = (sender as Button).Tag;

                this.SelectIndex((int)tag.Index);

                using (var repository = new LogRepository(Parametrs.LogURL, Parametrs.DebugURL, NITasks))
                    if (repository.Access)
                    {
                        var newItem = MainConf.Items.FirstOrDefault(x => x.ID == (int)tag.ID).Dublicate();
                        newItem.ChangeStatus(LogStatuses.Error);
                        newItem.AddChangeLog(new LogChange(
                            DateTime.Now,
                            "Status",
                            newItem.Status.ToString()
                        ));
                        repository.Update(MainConf.Items.FirstOrDefault(x => x.ID == (int)tag.ID), newItem);
                    }

                this.Initialize(InitializeType.Data, LoaderType.Load, false);
            }

        #endregion

        #region ClearData

            private void ClearData()
            {
                this.LBText.Items.Clear();
                this.LBTime.Items.Clear();
                this.LBDate.Items.Clear();
                this.LBStatus.Items.Clear();
                this.LBText.Update();
                this.LBDeadLine.Items.Clear();
                this.PnControl.Controls.Clear();
                this.PnInfoControl.Controls.Clear();
            }
            private void ClearDetailDate()
            {
                this.LBDetailDate.Items.Clear();
                this.LBDetailRUB.Items.Clear();
                this.LBDetailUAH.Items.Clear();
                this.LBDetailUSD.Items.Clear();
                this.LBDetailTime.Items.Clear();
            }

        #endregion

        #region DrawEvents

            private void LBStatus_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush myBrush = null;
                    switch (Utilities.GetEnum<LogStatuses>(this.LBStatus.Items[e.Index].ToString()))
                    {
                        case LogStatuses.Complite: myBrush = Brushes.Green; break;
                        case LogStatuses.Wait    : myBrush = Brushes.Blue; break;
                        case LogStatuses.Error   : myBrush = Brushes.Red; break;
                    }

                    if (this.LBStatus.Items[e.Index].ToString() == "At work") myBrush = Brushes.Yellow;

                    e.Graphics.DrawString(this.LBStatus.Items[e.Index].ToString(),
                        e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
                    e.DrawFocusRectangle();
                }
            }
            private void LBText_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush myBrush = Brushes.Black;
                    var shift = 0;

                    var item = MainConf.Items.First(x => x.ID == ((TableItem)this.LBText.Items[e.Index]).ID);

                    if (item.Complite.HasValue && (item.Complite.Value > item.DeadLine.Value))
                        myBrush = Brushes.Red;

                    if (item.Complite.HasValue && (item.Complite.Value.ToShortDateString() == DateTime.Now.ToShortDateString()))
                        myBrush = Brushes.Green;

                    if (item.IsPriority)
                    {
                        e.Graphics.DrawString("!!!", e.Font, Brushes.Red, new PointF(e.Bounds.X, e.Bounds.Y));
                        shift += 15;
                    }


                    e.Graphics.DrawString(((TableItem)this.LBText.Items[e.Index]).text,
                        e.Font, myBrush, new PointF(e.Bounds.X + shift, e.Bounds.Y));
                    e.DrawFocusRectangle();
                }
            }
            private void LBTime_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush myBrush = Brushes.Black;

                    e.Graphics.DrawString(this.LBTime.Items[e.Index].ToString(),
                        e.Font, myBrush, new PointF(e.Bounds.X, e.Bounds.Y));
                    e.DrawFocusRectangle();
                }
            }
            private void LBDate_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush myBrush = Brushes.Black;

                    e.Graphics.DrawString(this.LBDate.Items[e.Index].ToString(),
                        e.Font, myBrush, new PointF(e.Bounds.X, e.Bounds.Y));
                    e.DrawFocusRectangle();
                }
            }
            private void LBDetailUSD_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();

                    Brush brush = null;
                    if (e.Index > LBDetailUSD.Items.Count - 2 || e.Index == 11)
                        brush = Brushes.Red;
                    else
                        brush = Brushes.Black;

                    e.Graphics.DrawString(LBDetailUSD.Items[e.Index].ToString(),
                        e.Font, brush, new PointF(e.Bounds.X, e.Bounds.Y - (e.Index * 3)));
                    //e.DrawFocusRectangle();
                }
            }
            private void LBDetailRUB_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();

                    Brush brush = null;
                    if (e.Index > LBDetailRUB.Items.Count - 2 || e.Index == 11)
                        brush = Brushes.Red;
                    else
                        brush = Brushes.Black;

                    e.Graphics.DrawString(LBDetailRUB.Items[e.Index].ToString(),
                        e.Font, brush, new PointF(e.Bounds.X, e.Bounds.Y - (e.Index * 3)));
                    //e.DrawFocusRectangle();
                }
            }
            private void LBDetailUAH_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush brush = null;
                    if (e.Index > LBDetailUAH.Items.Count - 2 || e.Index == 11)
                        brush = Brushes.Red;
                    else
                        brush = Brushes.Black;

                    e.Graphics.DrawString(LBDetailUAH.Items[e.Index].ToString(),
                        e.Font, brush, new PointF(e.Bounds.X, e.Bounds.Y - (e.Index * 3)));
                    //e.DrawFocusRectangle();
                }
            }
            private void LBDetailTime_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush brush = null;
                    if (e.Index > LBDetailTime.Items.Count - 2 || e.Index == 11)
                        brush = Brushes.Red;
                    else
                        brush = Brushes.Black;

                    e.Graphics.DrawString(LBDetailTime.Items[e.Index].ToString(),
                        e.Font, brush, new PointF(e.Bounds.X, e.Bounds.Y - (e.Index * 3)));
                    //e.DrawFocusRectangle();
                }
            }
            private void LBDetailDate_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();

                    e.Graphics.DrawString(LBDetailDate.Items[e.Index].ToString(),
                        e.Font, Brushes.Black, new PointF(e.Bounds.X, e.Bounds.Y - (e.Index * 3)));
                    //e.DrawFocusRectangle();
                }
            }
            private void LBDeadLine_DrawItem(object sender, DrawItemEventArgs e)
            {
                if (e.Index != -1)
                {
                    e.DrawBackground();
                    Brush myBrush = Brushes.Black;
                    var item = MainConf.Items.FirstOrDefault(x =>x.ID == ((TableItem)LBText.Items[e.Index]).ID);
                    var deadLine = new DateTime(item.DeadLine.Value.Year, item.DeadLine.Value.Month, item.DeadLine.Value.Day);
                    var nowDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
                    if (deadLine < nowDate && !(item.Status == LogStatuses.Complite))
                        myBrush = Brushes.Red;
                    if (deadLine == nowDate && !(item.Status == LogStatuses.Complite))
                        myBrush = Brushes.DodgerBlue;

                    e.Graphics.DrawString(LBDeadLine.Items[e.Index].ToString(),
                        e.Font, myBrush, new PointF(e.Bounds.X, e.Bounds.Y));
                    e.DrawFocusRectangle();
                }
            }


        #endregion

        #region OtherEvents

            private void LBMain_SelectedIndexChanged(object sender, EventArgs e)
            {
                var LB = sender as ListBox;

                this.SelectIndex(LB.SelectedIndex);

                if (!TmrGO.Enabled && LBText.SelectedIndex != -1)
                {
                    MainConf.Session.SelectIndex = LBText.SelectedIndex;
                    MainConf.Session.SelectItem = MainConf.Items.FirstOrDefault(x =>x.ID == ((TableItem)LBText.Items[MainConf.Session.SelectIndex.HasValue ? MainConf.Session.SelectIndex.Value : 0]).ID); //SelectIndex = LBText.SelectedIndex;

                    LbTaskTime.Text = LogTime.Formated(MainConf.Session.SelectItem.GetTime(), FormatedTimeType.Width);
                }
            }
            private void TmrGO_Tick(object sender, EventArgs e)
            {
                LbTaskTime.Text = LogTime.Formated(MainConf.Session.TaskTime, FormatedTimeType.Width);
                LbToDayCash.Text = Money.Formated(Money.Calculate(
                    MainConf.Session.ToDayWorkTime,
                    MainConf.Setting.CashPerH,
                    MainConf.Currencys,
                    MainConf.Setting.CurrencyType
                ));

                LBTime.Items[MainConf.Session.SelectIndex.HasValue ? MainConf.Session.SelectIndex.Value : 0] = LogTime.Formated(MainConf.Session.TaskTime);
                LBTime.Update();

                Initialize(new List<InitializeType>() { 
                    InitializeType.Progress,
                    InitializeType.CashDetail
                }, LoaderType.Default, false);
            }
            private void Main_FormClosing(object sender, FormClosingEventArgs e)
            {
                Loader.Start();

                if (MainConf.Session.HasItem && TmrGO.Enabled)
                    MainConf.Session.SaveSession();
                using (var repository = new ConfRepository(Parametrs.ConfURL, Parametrs.DebugURL))
                    if (repository.Access)
                    {
                        var item = repository.Get().FirstOrDefault();
                        var newitem = new Configuration(
                            MainConf.Currencys,
                            item.Count,
                            item.CurrencyType,
                            item.Date,
                            item.OUTDate,
                            item.WorkTime
                        );
                        repository.Update(item, newitem);
                    }

                Loader.Stop();
            }
            private void LbDetail_MouseEnter(object sender, EventArgs e)
            {
                if (this.Height > 720)
                    (sender as Label).Image = Resources.DownSelect;
                else
                    (sender as Label).Image = Resources.UpSelect;
            }
            private void LbDetail_MouseLeave(object sender, EventArgs e)
            {
                if (this.Height > 720)
                    (sender as Label).Image = Resources.Down;
                else
                    (sender as Label).Image = Resources.Up;
            }

            private void TBSearch_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyData == Keys.Enter) InitializeData(TBSearch.Text);
            }
            private void TBAddValue_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter && TBAddDesc.Text != string.Empty)
                    BtAdd_Click(new object(), new EventArgs());
            }
            private void LB_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    var index = (sender as ListBox).SelectedIndex;
                    foreach (var control in PnInfoControl.Controls)
                    {
                        dynamic tag = (control as Button).Tag;
                        if (tag.Index == index)
                            BtTableInfo_Click(control, new EventArgs());
                    }
                }
            }


            private void TBNumber_Enter(object sender, EventArgs e)
            {
                TBAddNumber.Text = string.Empty;
                TBAddNumber.ForeColor = Color.Black;
            }
            private void TBDesc_Enter(object sender, EventArgs e)
            {
                TBAddDesc.Text = string.Empty;
                TBAddDesc.ForeColor = Color.Black;
            }

            private void TBNumber_Leave(object sender, EventArgs e)
            {
                if (TBAddNumber.Text == string.Empty)
                {
                    TBAddNumber.Text = "Number";
                    TBAddNumber.ForeColor = Color.Silver;
                }
            }
            private void TBDesc_Leave(object sender, EventArgs e)
            {
                if (TBAddDesc.Text == string.Empty)
                {
                    TBAddDesc.Text = "Desc of task";
                    TBAddDesc.ForeColor = Color.Silver;
                }
            }

            private void TBSearch_TextChanged(object sender, EventArgs e)
            {
                this.BtSearchCancle.Visible = TBSearch.Text != string.Empty;
            }

            private void CBSearchText_CheckedChanged(object sender, EventArgs e)
            {

                if (CBSearchText.Checked)
                {
                    CBSearchText.BackgroundImage = Resources.SearchTextActive;
                    CBSearchDate.BackgroundImage = Resources.SearchDate;
                    TBSearch.Visible = true;
                    BtSearchCancle.Visible = TBSearch.Text == string.Empty ? false : true;
                    DTPSearch.Visible = false;
                    CBSearchDate.Checked = false;
                }
                else if (!CBSearchDate.Checked)
                    CBSearchText.Checked = true;
            }
            private void CBSearchDate_CheckedChanged(object sender, EventArgs e)
            {
                if (CBSearchDate.Checked)
                {
                    CBSearchDate.BackgroundImage = Resources.SearchDateActive;
                    CBSearchText.BackgroundImage = Resources.SearchText;
                    CBSearchText.Checked = false;
                    TBSearch.Visible = false;
                    BtSearchCancle.Visible = false;
                    DTPSearch.Visible = true;
                }
                else if (!CBSearchText.Checked)
                    CBSearchDate.Checked = true;
            }
            private void CBPriority_CheckedChanged(object sender, EventArgs e)
            {
                this.CBPriority.BackgroundImage = this.CBPriority.Checked ? Resources.PriorityActive : Resources.Priority;
            }

        #endregion

        #region Utilities

            private void SaveToLogsAndClear()
            {
                if (Utilities.SaveToLogs(Parametrs.LogURL, Path.Combine(Parametrs.LogsFolderURL, DateTime.Now.ToShortDateString() + ".data")))
                {
                    MessageBox.Show("Saved", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    if (this.ClearCurrentLog())
                    {
                        MessageBox.Show("New log file is created", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        Initialize(new List<InitializeType>() {
                                            InitializeType.Data,
                                            InitializeType.DetailData,
                                            InitializeType.Notify,
                                            InitializeType.Progress,
                                        }, LoaderType.Load);
                    }
                    else
                        MessageBox.Show("New log file is don't created", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                    MessageBox.Show("Failed to save current log", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            private bool ClearCurrentLog()
            {
                if (Utilities.DeleteXmlDataLogFile(Parametrs.LogURL) && Utilities.CreateNewXmlDataLogFile(Parametrs.LogURL))
                    return true;
                return false;
            }
            private void SelectIndex(int index)
            {
                LBText.SelectedIndex = index;
                LBTime.SelectedIndex = index;
                LBStatus.SelectedIndex = index;
                LBDate.SelectedIndex = index;
                LBDeadLine.SelectedIndex = index;
            }
            private Button BtCreate(Color backColor, Color foreColor, Bitmap backgroundImage, ImageLayout backgroundImageLayout, FlatStyle flatStyle, Cursor cursor, int height, int width, int top, int left, Font font, object tag)
            {
                return new Button()
                {
                    BackColor = backColor,
                    BackgroundImage = backgroundImage,
                    BackgroundImageLayout = backgroundImageLayout,
                    FlatStyle = flatStyle,
                    ForeColor = foreColor,
                    Cursor = cursor,
                    Height = height,
                    Top = top,
                    Font = font,
                    Width = width,
                    Tag = tag,
                    Left = left
                };
            }

        #endregion



    }
}
